#include <pthread.h>
#include <stdio.h>
#include <SDL/SDL.h>

#include <GL/glew.h>
#include <GL/gl.h>

#include "sound.h"
#include "sync.h"
#include "system.h"

#include "cBackground.h"
#include "cNoise.h"
#include "cCubeTree.h"

#define WIDTH 640
#define HEIGHT 480

int main(int argc, char **argv) {
	if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
		printf("SDL ERROR\n");
		return -1;
    }

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE,            8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,          8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,           8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,          8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,          16);
	SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,         32);

	SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_OPENGL);

	glewInit();

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	Sync* sync = new Sync();
	System* system = new System(sync);

	// register components
	system->registerComponent(0, new cBackground(sync));
	system->registerComponent(2, new cCubeTree(sync));
	//system->registerComponent(9, new cNoise(sync));

	// set interval for the components
	system->activate(0, Interval(0, UNBOUND));
	system->activate(2, Interval(0, UNBOUND));
	//system->activate(9, Interval(0, UNBOUND));
	for (int i=0;i<5;i++) {
	}


	system->start();

	SDL_Event event;
	bool exit = false;
	while (!exit) {
	    while (SDL_PollEvent(&event) ) {
	        switch (event.type) {
	        	case SDL_KEYDOWN:
	        		if (event.key.keysym.sym == 27)
	        			exit = true;
	        		break;
	            case SDL_QUIT:
	            	exit = true;
	            	break;
	            default:
	            	printf("FPS: %.2f : %.2f\n", sync->fps(), sync->time());
	            	break;
	        }
	    }

		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

		float dt = sync->framestart();
	    system->run(dt);

	    SDL_GL_SwapBuffers();
	}

	printf("exit\n");
	system->stop();

	delete sync;
	delete system;
	SDL_Quit();
	pthread_exit(NULL);
	return 1;
}

